# coding: utf-8
import allure

from common import logger
from models import api_case_data_validate
from .requests_util import RequestsUtil
from ..public import AssertUtil, ExtractUtil


def APICaseMainFunction(case_data: dict):
    """
    API测试用例主要功能。
    API test case main function.
    :param case_data:
    :return:
    """
    model = api_case_data_validate(case_data)
    allure.dynamic.feature(model.module_name)
    allure.dynamic.story(model.api_name)
    allure.dynamic.title(model.case_name)
    allure.dynamic.description(model.case_description)
    allure.dynamic.tag(model.case_tags)
    text = '*' * 20 + f'用例开始, 请耐心等待, {model.case_name}, 正在执行中...' + '*' * 20
    with allure.step(text):
        logger.info(text)
        logger.debug(f'对用例数据进行预处理: {model.request_data}')
        model.request_data = ExtractUtil.use_extract_value(model.request_data)

    with allure.step('发送请求...'):
        response = RequestsUtil.send_request(**model.request_data)

    # 提取数据变量
    if model.extract:
        with allure.step('提取数据变量'):
            for key, value in model.extract.items():
                data = ExtractUtil.extract(response, key, *value)
                logger.info(f'提取数据: {data}')
    # 断言
    with allure.step('断言'):
        for assert_data in model.assert_data:
            if assert_data.method not in dir(AssertUtil()):
                raise ValueError(
                    f'Invalid assert method: {assert_data.method}\n '
                    'Please check the assert method in AssertUtil.\n'
                    f'Valid assert methods are: {dir(AssertUtil())}'

                )
            assert_data.actual = eval(assert_data.actual)
            adata = assert_data.dict()
            logger.info(f'Assert data: {adata}')
            getattr(AssertUtil, assert_data.method)(**adata)
    text = '*' * 20 + '用例结束' + '*' * 20
    with allure.step(text):
        logger.info(text)
